/**
 * Marcelo A Nagatomo
 * RA 062689
 * Atividade 1 - 14-09-2009
 */


/***************************************************************************/
/****   CLIENTE   **********************************************************/
/***************************************************************************/


#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#define MAXLINE 4096

/**
 *	Client TCP
 *	
 *	Use: ./client IP_SERVER
 */
int main(int argc, char **argv) {
   int    sockfd, n;
   char   recvline[MAXLINE + 1];
   char   error[MAXLINE + 1];
   struct sockaddr_in servaddr;

   // InputError Handling
   if (argc != 2) {
      strcpy(error,"uso: ");
      strcat(error,argv[0]);
      strcat(error," <IPaddress>");
      perror(error);
      exit(1);
   }

   // Create the socket.
   // Parameters:
   //	- AF_INET (Ipv4):
   //		This designates the address format that goes with the Internet namespace.
   //	- SOCK_STREAM (TCP): 
   //		It operates over a connection with a particular remote socket,
   //		and transmits data reliably as a stream of bytes.
   //	- 0
   //		Common Applications
   if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
      perror("socket error");
      exit(1);
   }

   // allocates the memory with '0'
   bzero(&servaddr, sizeof(servaddr));		//
   servaddr.sin_family = AF_INET;			// set format addres
   servaddr.sin_port   = htons(3000);		//** Port: modified line in ex4**//
   
   // This function converts the character string src into a network address
   // structure in the af address family, then copies the network address structure to dst
   if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
      perror("inet_pton error");
      exit(1);
   }

   // The  connect()  system  call  connects  the  socket referred to by the file descriptor 'sockfd' to the
   // address specified by 'serv_addr'.  The addrlen argument specifies the size of serv_addr. The format
   // of  the  address in 'serv_addr' is determined by the address space of the socket 'sockfd';
   // see socket(2) for further details.
   if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
      perror("connect error");
      exit(1);
   }
   
   // Get socket namespace
   socklen_t serveraddr_len = sizeof(servaddr);
   if (getsockname(sockfd, (struct sockaddr *) &servaddr, &serveraddr_len) >= 0){
	  printf("Local IP address is: %s\n", inet_ntoa(servaddr.sin_addr));
	  printf("Local port is: %d\n", (int) ntohs(servaddr.sin_port));

   } else {
	  perror("getsockname error");
      exit(1);
   
   }

   // Read data of 'sockfd' and save in 'recvline'.
   while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
      recvline[n] = 0;
	  // OutputError Handling
      if (fputs(recvline, stdout) == EOF) {
         perror("fputs error");
         exit(1);
      }
   }

   // InputError Handling
   if (n < 0) {
      perror("read error");
      exit(1);
   }
  
   // Exit
   exit(0);
}